package com.open.validator;

/**
 * @author: system
 * @Date: 2024/4/19 15:09
 * @Version: V1.0
 * @description: desc:
 */


import com.open.validator.impl.ConditionalValidator;


import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * 补充校验
 * 作用在类定义上，主要完成某个字段依赖另外的字段时的校验
 * 当依赖字段所选值为指定值，被校验字段必须有值
 * 使用方法：
 *
 * @author codex
 * @Conditional.List(
 * @Conditional(field = "info",values = {"zhangsan","lisi"},depFields = {@Field(name = "edu")}),
 * @Conditional(field = "edu",values = {"dazhuan","benke"},depFields = {@Field(name = "name"),@Field(name="info")})
 * )
 * 上面的例子说明，只有当依赖字段edu有值时，info字段必须有值，且必须为zhangsan或者lisi之一
 * 另外一条意思是说：当字段name、info有值时，edu字段必须有值
 * 还可以指定最大最小值
 */
@Repeatable(Conditional.List.class)
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ConditionalValidator.class})
public @interface Conditional {

    String message() default "This field must set value, can not empty.";

    String blankMessage() default "This field must set value, can not empty.";

    String sizeMessage() default "This field length must be within a certain range.";

    String valuesMessage() default "Invalid value";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    /**
     * @return size the element must be higher or equal to
     */
    int min() default 0;

    /**
     * @return size the element must be lower or equal to
     */
    int max() default Integer.MAX_VALUE;

    // 需要校验的字段
    String field();

    // 字段允许的值，必须是其中值之一
    String[] values() default {};

    // 带值的字段
    Field[] depFields() default {};


    /**
     * Defines several {@link Conditional} annotations on the same element.
     *
     * @see Conditional
     */
    @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
    @Retention(RUNTIME)
    @Documented
    @interface List {

        Conditional[] value();
    }
}